﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace DBTool
{
    using CREATE_TABLE_NAME = System.String;
    using INSERT_TABLE_NAME = System.String;

    public abstract class TableMeta
    {
        protected List<CREATE_TABLE_NAME> _createTableName;
        protected List<KeyValuePair<INSERT_TABLE_NAME, string[]>> _rowGropList;

        protected TableMeta()
        {
            _createTableName = new List<INSERT_TABLE_NAME>();
            _rowGropList = new List<KeyValuePair<INSERT_TABLE_NAME, INSERT_TABLE_NAME[]>>();
        }

        public bool Parse(string filePath)
        {
            CSVReader originalTable = new CSVReader(filePath);

            string exportPath = Path.GetDirectoryName( filePath ) + "/" + Config._parseFolderName;

            DeleteTable(exportPath);

            CreateTable(exportPath);

            InsertTitleToTable(originalTable, exportPath);

            InsertContentToTable(originalTable, exportPath);

            ExtraProcessByTable( exportPath ); // Table 별 추가 처리

            if ( false == FieldLengthExceptionChecker() )
                return false;

            return true;
        }

        private bool FieldLengthExceptionChecker()
        {
            foreach (KeyValuePair<INSERT_TABLE_NAME, string[]> insertGroup in _rowGropList)
            {
                string[] tableTitles = DBConnect.Instance.GetTableTitles(insertGroup.Key);

                if( null == tableTitles )
                    continue;

                if ( tableTitles.Length == insertGroup.Value.Length )
                    continue;

                MessageBox.Show("TableName : " + insertGroup.Key + "\n" +
                                "DBTable ColumnLength : " + tableTitles.Length + "\n" +
                                "MetaData ColumnLength : " + insertGroup.Value.Length,
                                "File Is Exist", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            return true;
        }

        private void DeleteTable(string exportPath)
        {
            foreach (string tablePath in _createTableName)
            {
                string deletePath = exportPath + "/" + tablePath + Config._exportFileExt;

                //DeleteTable
                if ( true == File.Exists( deletePath ) )
                    File.Delete( deletePath );

                // Sync delete File
                while (true == File.Exists(deletePath)) { }
            }
        }

        private void CreateTable(string exportPath)
        {
            //CreateTable
            if (false == Directory.Exists(exportPath))
                Directory.CreateDirectory(exportPath);

            // Sync Create Directory
            while (false == Directory.Exists(exportPath)) { }

            foreach (string tableName in _createTableName)
            {
                string createFilePath = exportPath + "/" + tableName + Config._exportFileExt;

                if (true == File.Exists(createFilePath))
                {
                    MessageBox.Show("Error. " + tableName + " is Exist", "File Is Exist", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    continue;
                }

                StreamWriter fileWriter = new StreamWriter( createFilePath, false, Encoding.UTF8 );
                fileWriter.Close();
            }
        }

        private void InsertTitleToTable(CSVReader originalTable, string exportPath)
        {
            foreach (string tableName in _createTableName)
            {
                string createFilePath = exportPath + "/" + tableName + Config._exportFileExt;

                if (false == File.Exists(createFilePath))
                {
                    MessageBox.Show("Error. " + tableName + " is Not Exist", "File Is Not Exist", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    continue;
                }

                string[] dbTableTitles = DBConnect.Instance.GetTableTitles(tableName);
        
                if (null == dbTableTitles)
                {
                    MessageBox.Show(tableName + " DB Columns Not Exist", "Table Column Not Exist", MessageBoxButtons.OK, MessageBoxIcon.Error);
                
                    dbTableTitles = originalTable.GetColumnTitle();
                }

                string insertTitleRow = "";
                foreach (string column in dbTableTitles)
                {
                    insertTitleRow += column;
                    insertTitleRow += ",";
                }

                insertTitleRow = insertTitleRow.TrimEnd(',');
                insertTitleRow += "\r\n";

                File.AppendAllText(createFilePath, insertTitleRow);
            }
        }

        private void InsertContentToTable(CSVReader originalTable, string exportPath)
        {
            for ( int rowCount = 1; rowCount < originalTable.GetRowCount() ; ++rowCount )
                RowSeperateGroupAndInsert(rowCount, originalTable, exportPath);
        }

        private void RowSeperateGroupAndInsert(int rowCount, CSVReader originalTable, string exportPath)
        {
            foreach (KeyValuePair<INSERT_TABLE_NAME, string[]> insertGroup in _rowGropList)
            {
                string[] group = insertGroup.Value;
                string insertRow = "";

                foreach (string column in group)
                {
                    if (true == column.Contains("CUSTOM_FIELD"))
                    {
                        string[] customSplit = column.Split(':');
                        insertRow += customSplit[1];
                    }
                    else
                        insertRow += originalTable.Find(rowCount, column);

                    insertRow += ",";
                }

                insertRow = insertRow.TrimEnd(',');
                
                insertRow += "\r\n";

                File.AppendAllText(exportPath + "/" + insertGroup.Key + Config._exportFileExt, insertRow);
            }
        }

        protected virtual void ExtraProcessByTable( string exportPath ) { }

        public string[] GetCreateTableName()
        {
            if (null == _createTableName)
            {
                MessageBox.Show("_createTableNameList Is Null", "Table Column Not Exist", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }

            return _createTableName.ToArray<string>();
        }
    }
}
